class CustomFrustumPrimitive {
  constructor(options) {
    this.lightCamera = options.lightCamera;
    this.position = this.lightCamera.positionWC;
    this._position = undefined;
  }

  getGeometry() {
    const scratchRight = new Cesium.Cartesian3();
    const scratchRotation = new Cesium.Matrix3();
    const scratchOrientation = new Cesium.Quaternion();
    const position = this.lightCamera.positionWC;
    const direction = this.lightCamera.directionWC;
    const up = this.lightCamera.upWC;
    let right = this.lightCamera.rightWC;
    right = Cesium.Cartesian3.negate(right, scratchRight);
    let rotation = scratchRotation;
    Cesium.Matrix3.setColumn(rotation, 0, right, rotation);
    Cesium.Matrix3.setColumn(rotation, 1, up, rotation);
    Cesium.Matrix3.setColumn(rotation, 2, direction, rotation);
    let orientation = Cesium.Quaternion.fromRotationMatrix(rotation, scratchOrientation);
    return new Cesium.FrustumOutlineGeometry({
      frustum: this.lightCamera.frustum,
      origin: position,
      orientation: orientation
    });
  }

  getPrimitive() {
    let geometry = this.getGeometry();
    let instance = new Cesium.GeometryInstance({
      geometry,
      id: Math.random().toString(36).substr(2),
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOWGREEN), //Cesium.Color.YELLOWGREEN
        show: new Cesium.ShowGeometryInstanceAttribute(true)
      }
    });
    return new Cesium.Primitive({
      geometryInstances: [instance],
      asynchronous: false, //关闭异步绘制，否则动态更新时无法渲染
      appearance: new Cesium.PerInstanceColorAppearance({
        flat: true,
        translucent: false
      })
    });
  }

  update(context, frameState, commandList) {
    if (this.position.equals(this._position)) {
      if (this._primitive) {
        this._primitive.update(context, frameState, commandList)
      }
      return;
    }
    this._position = this.position.clone();
    this._primitive && this._primitive.destroy();
    this._primitive = this.getPrimitive();
    if (!this._primitive) return;
    this._primitive.update(context, frameState, commandList);
  }

  isDestroyed() {
    return false;
  }

  destroy() {
    this._primitive = this._primitive && this._primitive.destroy();
    return Cesium.destroyObject(this);
  }
}

export default CustomFrustumPrimitive;